from signal import read_signal_from_wav_file, read_signal_from_string
from spectrogram import create_spectrogram_for_signal
from analyzer import match
import numpy as np
from norm import normalize_spectrogram


class SpectrogramComparator:
    def __init__(self, application_context):
        self.application_context = application_context
        
    def compare_audio_track_against_db(self, audio_file):
        # read the configuration
        fft_config = self.application_context.fftconfig
        fftlen = int(fft_config['fftlen'])
        fmax = int(fft_config['fmax'])
        samplespersecond = int(fft_config['samplespersecond'])
        fbpp = int(fft_config['fbpp'])
        
        # prepare DAOs
        dao_species = self.application_context.species_dao
        dao_template = self.application_context.template_dao
        
        # load the audio track
        track_signal, track_sampling_freq = read_signal_from_wav_file(audio_file)
        track_spectrogram = create_spectrogram_for_signal(track_signal, track_sampling_freq, fftlen, samplespersecond)
        normalized_track = normalize_spectrogram(track_spectrogram, fbpp, samplespersecond, fmax)
        
        species_list = dao_species.get_species_list()
        results = []
        for species in species_list:
            template_list = dao_template.get_templates_for_species(species)
            for template in template_list:
                templateData = dao_template.load_sound_data_for_template(template)
                template_signal, template_signal_sampling_freq = read_signal_from_string(templateData)
                template_spectrogram = create_spectrogram_for_signal(template_signal, template_signal_sampling_freq, fftlen, samplespersecond)
                normalized_template = normalize_spectrogram(template_spectrogram, fbpp, samplespersecond, fmax)
                correlation_map = match(normalized_track, normalized_template)
                maximum = np.nanmax(np.abs(correlation_map))
                results.append((template, maximum))
        return results
